<?php


namespace App\Services;

use App\Exceptions\InvalidRequestException;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;

class LoginService
{
    // 微信网页授权
    public function weChatH5Login($wxUser)
    {

        if (!$user = User::query()->where('openid', $wxUser->id)->first()) { // 如果用户第一次登录
            $user = new User([
                'name' => $wxUser->name,
                'nickname' => $wxUser->nickname,
                'avatar' => $wxUser->avatar,
                'email' => $wxUser->email,
                'provider' => $wxUser->provider,
                'sex' => $wxUser->original['sex'],
                'language' => $wxUser->original['language'],
                'city' => $wxUser->original['city'],
                'province' => $wxUser->original['province'],
                'country' => $wxUser->original['country'],
            ]);
            $user->openid = $wxUser->id;
            $user->access_token = $wxUser->token;
            $user->save();
        }

        $user = $this->saveToken($user);
        return $user;
    }

    // 生成游客账号,并登录
    public function visitorLogin()
    {
        // 生成游客账号并设置在cookie中
        $user = User::query()->create([
            'provider' => User::PROVIDER_LOCAL
        ]);
        $user = $this->saveToken($user);
        return $user;
    }

    // 保存用户令牌
    public function saveToken(User $user, $is_generate_refresh_token = true)
    {
        // 生成长度为60的令牌
        $token = md5(date('YmdHis')) . Str::random(28);
        $key = "Bearer " . $token;
        Cache::tags(['token'])->put($key, $user, 7200);
        $user->api_token = $token;
        $user->save();

        if ($is_generate_refresh_token) {
            // 生成refresh_token
            $user->refresh_token = $this->generateRefreshToken($key, $user->id);
        }

        return $user;
    }

    /**
     * 客户端可以通过refress_token 获取新的access_token
     * @param $key 缓存中token的key
     */
    private function generateRefreshToken($key, $user_id)
    {
        // 随机一个key
        $refreshToken = md5(date('YmdHis')) . Str::random(30);
        $data = [
            'api_token_key' => $key,
            'user_id' => $user_id
        ];
        Cache::tags(['token'])->put($refreshToken, $data, 1314000);  // 无痛刷新key可以使用365天
        return $refreshToken;
    }

    public function refreshApiToken($refreshToken)
    {
        if (!Cache::tags(['token'])->has($refreshToken)) {
            throw new InvalidRequestException('refresh_token已过期', 401);
        }

        $data = Cache::tags(['token'])->get($refreshToken);
        $user = User::find($data['user_id']);
        // 遗忘原本的key
        Cache::tags(['token'])->forget($data['api_token_key']);
        // 重新生成api_token, 但是不重新生成refresh_token
        $user = $this->saveToken($user, false);
        $user->refresh_token = $refreshToken;

        return $user;
    }
}
